/**
 * @file         scc_lmu.h
 * @brief        定位模块升级基类
 * @note    
 * @author       dengdeshou
 * @date         2020-04-23
 * @version      1.0
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2020-04-23   <td>1.0                   <td>Dengdeshou      <td>创建初始版本
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */

#ifndef _SCC_LMU_H_
#define _SCC_LMU_H_

#include "ofc/ofc_types.h"
#include "ofc/ofc_object.h"
#include "lmu/scc_lmu_error.h"
#include "lmu/scc_lmu_instance.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifdef LMU_LOG_DEBUG
    #define LOG_IF(b, fmt, args...) ((b) == (1) ? (MFC_LOG_DEBUG(fmt, ##args)) : 0)
#else
    #define LOG_IF(b, fmt, args...)
#endif

/**
 * 命令执行结果
 */
enum TSccLmuCmdResultTag
{
    kSccLmuCmdResultOk = 0, ///< 执行成功
    kSccLmuCmdResultNotSupport = 1, ///< 命令不支持, 重发或失败退出
    kSccLmuCmdResultFail = 2, ///< 执行失败，模块有应答, 但是应答失败
    kSccLmuCmdResultDoing = 3, ///< 执行过程中
    kSccLmuCmdResultTimeout = 4, ///< 执行超时    
    kSccLmuCmdResultNone = 5, ///< 命令未开始执行
    kSccLmuCmdResultExit = 6, ///< 退出升级
};
typedef enum TSccLmuCmdResultTag TSccLmuCmdResult;

/**
 * 命令执行状态
 */
typedef struct TSccLmuCmdStatusTag TSccLmuCmdStatus;
struct TSccLmuCmdStatusTag
{
    Byte *cmd_data; ///< 命令数据
    Word cmd_len; ///< 命令长度

    TSccLmuCmdResult cmd_result; ///< 命令执行结果
    TTime cmd_ticks; ///< 命令开始执行的时间戳,单位：毫秒
    Byte cmd_try_times; ///< 命令尝试次数
};
    
/**
 * 定位模块升级类型
 */
enum TSccLmuUpgradeTypeTag
{
    kSccLmuUpgradeTypeAuto = 0, ///< 自适应模块
    kSccLmuUpgradeTypeAssign = 1, ///< 指定模块模式
};
typedef enum TSccLmuUpgradeTypeTag TSccLmuUpgradeType;
 
/**
 * 波特率定义
 */
enum TSccLmuBaudrateTag
{
    kSccLmuBaudrate9600 = 0x01, ///< 波特率9600
    kSccLmuBaudrate19200 = 0x02, ///< 波特率19200
    kSccLmuBaudrate38400 = 0x03, ///< 波特率38400
    kSccLmuBaudrate57600 = 0x04, ///< 波特率57600
    kSccLmuBaudrate115200 = 0x05, ///< 波特率115200
};
typedef enum TSccLmuBaudrateTag TSccLmuBaudrate;

/**
 * 升级结果通知事件
 */
typedef struct TSccLmuOnUpgradeResultTag TSccLmuOnUpgradeResult;
struct TSccLmuOnUpgradeResultTag
{
    TSccLmuDoUpgradeResult Method;
    void *object;
};

typedef struct TSccLmuOnWriteTag TSccLmuOnWrite;
struct TSccLmuOnWriteTag
{
    TSccLmuDoWrite Method;
    void *object;
};

typedef struct TSccLmuOnReadTag TSccLmuOnRead;
struct TSccLmuOnReadTag
{
    TSccLmuDoRead Method;
    void *object;
};

typedef struct TSccLmuOnGetDataPositionTag TSccLmuOnGetDataPosition;
struct TSccLmuOnGetDataPositionTag
{
    TSccLmuDoGetDataPosition Method;
    void *object;
};

typedef struct TSccLmuOnSetBaudrateTag TSccLmuOnSetBaudrate;
struct TSccLmuOnSetBaudrateTag
{
    TSccLmuSetBaudrate Method;
    void *object;
};

typedef struct TSccLmuOnProgressTag TSccLmuOnProgress;
struct TSccLmuOnProgressTag
{
    TSccLmuProgress Method;
    void *object;
};

/**
 * 定位升级模块类
 */
typedef struct TSccLmuTag TSccLmu;
struct TSccLmuTag
{
PROTECTED
    TOfObject parent_;  ///< 基类
    
PROTECTED
    TOfVirtualMethod Destroy_; ///< 析构事件
    
PRIVATE
    Byte *recv_buf_; ///< 接收缓冲区
    Int16 recv_size_; ///< 接收缓冲区大小
    Int16 recv_buf_pos_;  ///< 接收缓冲区当前位置,初始值为-1

    Byte *send_buf_; ///< 发送缓冲区
    Int16 send_size_; ///< 发送缓冲区大小
    Int16 send_buf_pos_; ///< 发送缓冲区当前位置,初始值为-1
    TSccLmuErrorCodeEnum error_code_; ///< 错误码
    DWord ticks_; ///< 当前系统时间戳
    DWord timeout_; ///< 超时时间
    DWord img_size_; ///< 固件大小
    DWord img_offset_; ///< 升级固件在文件中的偏移地址
    Word img_total_packet_; ///< 总包数
    Word img_cur_packet_; ///< 当前传输包序号，默认为0
    Word img_packet_size_; ///< 每包大小
    Word img_packet_max_size_; ///< 每包最大长度
    TSccLmuBaudrate baudrate_; ///< 当前升级波特率
    Byte upgrade_try_times_; ///< 重新升级尝试次数
    Byte state_; ///< 当前升级状态
    Byte log_flag_; ///< 日志打印标志，默认0，不打印，1打印
    TSccLmuCmdStatus cmd_status_; ///< 命令执行状态    
PUBLIC
    /// OnGetDataPosition,读取固件数据流
    TSccLmuOnGetDataPosition OnGetDataPosition;
    /// OnResultEvent,升级结果通知(接口)
    TSccLmuOnUpgradeResult OnResultEvent;
    /// OnSendEvent,向模块发送数据的接口
    TSccLmuOnWrite OnWriteEvent;
    /// OnReadEvent,读取模块数据事件
    TSccLmuOnRead OnReadEvent;
    /// 设置模块升级波特率,如不实现此事件，则用默认9600波特率
    TSccLmuOnSetBaudrate OnSetBaudrate;
    /// 升级进度通知事件
    TSccLmuOnProgress OnProgress;
};

/**
 * 构造函数
 * @param self: 对象指针
 * @param recv_buf: 传入接收缓冲区，供内部使用
 * @param recv_buf_size: 接收缓冲区大小
 * @param send_buf: 传入发送缓冲区，供内部使用
 * @param send_buf_size: 发送缓冲区大小
 * @return
 */
void TSccLmuCreate(TSccLmu *self, Byte *recv_buf, Int32 recv_buf_size, Byte *send_buf, Int32 send_buf_size);

/**
 * 设置升级状态为完成状态
 * @param self: TSccLmu对象指针
 * @param error_code: 错误码
 * return
 */
void TSccLmuSetStatusFinish(TSccLmu *self, TSccLmuErrorCodeEnum error_code);

/**
 * 升级初始化
 * @param scc_lmu: TSccLmu的指针
 * return 升级状态
 */
void TSccLmuInit(TSccLmu *self);

/**
 * 设置回调函数
 * @param scc_lmu: TSccLmu对象指针
 * @param func: 回调函数指针
 * return 打印日志标志，0-不打印，1-打印
 */
void TSccLmuSetCallBack(TSccLmu *self, void *func, Byte func_type, void *sender);

#ifdef __cplusplus
}
#endif
#endif
